﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using WindowsFormsApp2.Util;
using Emgu.CV;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;
using System.Web;
using System.IO;
using System.Collections.Specialized;
using System.Net;
using System.Security.Cryptography;



namespace WindowsFormsApp2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        string pathElec;
        string pathScan;
        private void 原图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string path = DialogHelper.ShowOpenImageFile();
            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            pathElec = path;
        }

        private void 对比图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string path = DialogHelper.ShowOpenImageFile();
            if (string.IsNullOrEmpty(path))
            {
                return;
            }
            pathScan = path;
        }

        private void 处理ToolStripMenuItem_Click(object sender, EventArgs e)
        {


            Bitmap bitDiffer = null;
            using (Bitmap bitElec = new Bitmap(pathElec))
            {
                using (Bitmap bitScan = new Bitmap(pathScan))
                {
                    //检测位移
                    Image<Bgr, Byte> srcImg = new Image<Bgr, Byte>(bitElec);
                    Image<Gray, Byte> srcImg1 = srcImg.Convert<Gray, Byte>();
                    Image<Bgr, Byte> dstImg = new Image<Bgr, Byte>(bitScan);
                    Image<Gray, Byte> dstImg1 = dstImg.Convert<Gray, Byte>();
                    long matchTime; float xCount; float yCount;

                    Match matchh = new Match();
                    Mat x = srcImg1.Mat;
                    Mat y = dstImg1.Mat;
                    //检测位移并放大位移10
                    matchh.DrawReturn10multiple(x, y, out matchTime, out xCount, out yCount);

                    #region  umat放大图片
                    UMat matImageElec = srcImg.ToUMat();
                    UMat matImageScan = dstImg.ToUMat();
                    UMat newumat = new UMat();
                    Size s = new Size(new Point(srcImg.Width * 10, srcImg.Height * 10));
                    CvInvoke.Resize(matImageElec, newumat, s);
                    
                    newumat.Save(Application.StartupPath + @"\放大处理.tif");
                    pathElec = Application.StartupPath + @"\放大处理.tif";
                    #endregion
                    //adjustNo1
                    #region 调整图像位移
                    ImageTZ imgTZ = new ImageTZ(pathElec, pathScan);
                    Bitmap bm = new Bitmap(2, 2);
                    Bitmap bitlittle = new Bitmap(pathScan);
                    bm = imgTZ.tiaozhengtp(pathElec, Convert.ToInt32(xCount), Convert.ToInt32(yCount));

                    bm = imgTZ.CutStipulateSizeFromLeft(bm, srcImg.Width*10, srcImg.Height*10);
                    //bm = imgTZ.CutBigTiff(bitlittle, bm);
                    bitlittle.Dispose();
                    try
                    {
                        bm.Save(Application.StartupPath + @"\位移处理.tif");

                    }
                    catch { }
                    #endregion

                    #region 将图1压缩到原来尺寸  算法resize 
                    //算法1
                    Image<Bgr, Byte> srcImgCompress = new Image<Bgr, Byte>(bm);
                    UMat matCompress = srcImgCompress.ToUMat();
                    UMat newMatCompress = new UMat();
                    Size sCompress = new Size(new Point (srcImgCompress.Width/10,srcImgCompress.Height/10));
                    CvInvoke.Resize(matCompress,newMatCompress,sCompress,3);
                    newMatCompress.Save(Application.StartupPath+ @"\还原.tif");
                    pathElec = Application.StartupPath + @"\还原.tif";
                    #endregion


                    #region 颜色插值算法               
                    Bitmap bitElecDeal = new Bitmap(Application.StartupPath + @"\还原.tif");
                    string threshold = textBox1.Text;
                    ImageBJ bj = new ImageBJ(bitElecDeal, bitScan,threshold);
                    bitDiffer = bj.ChangePicwhiteBg(bitElecDeal, bitScan, Convert.ToInt32(threshold));
                    bitDiffer.Save(Application.StartupPath + @"\对比结果.tif");
                    #endregion
                }
            }

            //pictureBox1.Image = bitDiffer;
            pictureBox1.Image = Image.FromFile(Application.StartupPath + @"\对比结果.tif");
            pictureBox1.Show();
        }

        private void toolStripMenuItem1_Click(object sender, EventArgs e)
        {
            Image<Bgr, byte> image = new Image<Bgr, byte>(320, 240, new Bgr(0, 0, 255));//创建一张320*240尺寸颜色为红色的图像。  
            imageBox1.Image = image;//在ImageBox1控件中显示所创建好的图像。
        }

        private void toolStripMenuItem2_Click(object sender, EventArgs e)
        {
            Bitmap bitmap = new Bitmap("001.jpg");
            //Bitmap转Image<Bgr, byte>
            Image<Bgr, byte> image = new Image<Bgr, byte>(bitmap);
            //Image<Bgr, byte>转Bitmap
            Bitmap _bitmap = image.ToBitmap();
            Bitmap _bitmap1 = image.Bitmap;


            //Image<Bgr, byte>转Mat
            Mat _mat = image.Mat;
            Mat _mat1 = image.ToUMat().GetMat(Emgu.CV.CvEnum.AccessType.Fast);


            //Mat转Image<Bgr, byte>
            Image<Bgr, byte> _image = _mat.ToImage<Bgr, byte>();
            //Mat转UMat
            UMat umat = _mat.GetUMat(Emgu.CV.CvEnum.AccessType.Fast);
            //UMat转Mat
            Mat mat = umat.GetMat(Emgu.CV.CvEnum.AccessType.Fast);
            //UMat转Image<Bgr, byte>
            Image<Bgr, byte> _image1 = umat.ToImage<Bgr, byte>();
            //Image<Bgr, byte>转UMat
            UMat umat2 = image.ToUMat();

            //imgLoad.Image = image;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }

        private void 计算每行像素值ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bitmap bit = new Bitmap(pathElec);
            Image<Bgr, byte> bitImg = new Image<Bgr, byte>(bit);
            UMat bitU = bitImg.ToUMat();
            //灰度化
            UMat bitGray = new UMat();
            UMat bit3Channel = new UMat();
            CvInvoke.Decolor(bitU, bitGray, bit3Channel);
            bitGray.Save("gaaaa.jpg");
            //二值化
            UMat bitTh = new UMat();
            CvInvoke.Threshold(bitGray, bitTh,200,255,Emgu.CV.CvEnum.ThresholdType.Binary);
            bitTh.Save("thhhh.jpg");

            Bitmap bitCalc = new Bitmap("thhhh.jpg");
            int count = 0;
            int hanghao = 0;
            //计算每行像素值，打印
            for (int i = 0; i < bitCalc.Height; i++)
            {
                for (int j = 0; j < bitCalc.Width; j++)
                {
                    if (bitCalc.GetPixel(j,i).R==0)
                    {
                        count++;
                    }
                }
                if(count!=0 )textBox2.AppendText(i.ToString()+"--"+count.ToString() + "\r\n");
                hanghao++;
                count = 0;
            }
            MessageBox.Show("ok");
        }

        private void 计算对比图每行ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bitmap bit = new Bitmap(pathScan);
            Image<Bgr, byte> bitImg = new Image<Bgr, byte>(bit);
            UMat bitU = bitImg.ToUMat();
            //灰度化
            UMat bitGray = new UMat();
            UMat bit3Channel = new UMat();
            CvInvoke.Decolor(bitU, bitGray, bit3Channel);
            bitGray.Save("gaaaas.jpg");
            //二值化
            UMat bitTh = new UMat();
            CvInvoke.Threshold(bitGray, bitTh, 200, 255, Emgu.CV.CvEnum.ThresholdType.Binary);
            bitTh.Save("thhhhs.jpg");

            Bitmap bitCalc = new Bitmap("thhhhs.jpg");
            int count = 0;
            int hanghao = 0;
            //计算每行像素值，打印
            for (int i = 0; i < bitCalc.Height; i++)
            {
                for (int j = 0; j < bitCalc.Width; j++)
                {
                    if (bitCalc.GetPixel(j, i).R == 0)
                    {
                        count++;
                    }
                }
                if (count != 0) textBox3.AppendText(i.ToString()+ "--"+count.ToString() + "\r\n");
                hanghao++;
                count = 0;
            }
        }

        private void 膨胀腐蚀处理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bitmap bitmap = new Bitmap(pathElec);
            Image<Bgr, byte> img = new Image<Bgr, byte>(bitmap);
            Image<Gray, byte> gray = new Image<Gray, byte>(img.Width, img.Height);
            Image<Bgr, byte> resuImage = new Image<Bgr, byte>(img.Width, img.Height);
            Image<Gray, byte> dnc = new Image<Gray, byte>(img.Width, img.Height);
            CvInvoke.CvtColor(img, gray, ColorConversion.Bgra2Gray);//灰度化
            //做一下膨胀，x与y方向都做，但系数不同
            var kernal = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(4, 4), new Point(1, 1));
            CvInvoke.Erode(gray, gray, kernal, new Point(0, 2), 1, BorderType.Default, new MCvScalar());
            //CvInvoke.Canny(gray, gray, 100, 60);
            CvInvoke.Threshold(gray, gray, 100, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);//二值化
            //检测连通域，每一个连通域以一系列的点表示，FindContours方法只能得到第一个域
           Bitmap graybtm = gray.ToBitmap();
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
            CvInvoke.FindContours(gray, contours, dnc, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
            var color = new MCvScalar(0, 0, 255);
            Console.WriteLine(contours.Size);
            List<Rectangle>  rects = new List<Rectangle>();
            //开始遍历
            for (int i = 0; i < contours.Size; i++)
            {
                //得到这个连通区域的外接矩形
                var rect = CvInvoke.BoundingRectangle(contours[i]);
                //如果高度不足，或者长宽比太小，认为是无效数据，否则把矩形画到原图上
                if (rect.Height > 10 && (rect.Width * 1.0 / rect.Height) > 0.2)
                {
                    rects.Add(rect);


                    //CvInvoke.DrawContours(resuImage, contours, i, color);//画轮廓
                    // CvInvoke.Rectangle(resuImage, rect, color);//画矩形框
                    CvInvoke.Rectangle(img, rect, color);//画矩形框

                }
            }

            // return img.ConcateVertical(resuImage).ToBitmap();
            img.Save("aaaaa.jpg");
            imageBox2.Image = img;
            imageBox2.Show();
            MessageBox.Show(rects.Count.ToString());
        }

        private void 膨胀处理对比图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Bitmap bitmap = new Bitmap(pathScan);
            Image<Bgr, byte> img = new Image<Bgr, byte>(bitmap);
            Image<Gray, byte> gray = new Image<Gray, byte>(img.Width, img.Height);
            Image<Bgr, byte> resuImage = new Image<Bgr, byte>(img.Width, img.Height);
            Image<Gray, byte> dnc = new Image<Gray, byte>(img.Width, img.Height);
            CvInvoke.CvtColor(img, gray, ColorConversion.Bgra2Gray);//灰度化
            //做一下膨胀，x与y方向都做，但系数不同
            var kernal = CvInvoke.GetStructuringElement(ElementShape.Rectangle, new Size(4, 4), new Point(1, 1));
            CvInvoke.Erode(gray, gray, kernal, new Point(0, 2), 1, BorderType.Default, new MCvScalar());
            //CvInvoke.Canny(gray, gray, 100, 60);
            CvInvoke.Threshold(gray, gray, 100, 255, ThresholdType.BinaryInv | ThresholdType.Otsu);//二值化
                                                                                                   //检测连通域，每一个连通域以一系列的点表示，FindContours方法只能得到第一个域
            Bitmap graybtm = gray.ToBitmap();
            VectorOfVectorOfPoint contours = new VectorOfVectorOfPoint();
           
            CvInvoke.FindContours(gray, contours, dnc, RetrType.Ccomp, ChainApproxMethod.ChainApproxSimple);
            var color = new MCvScalar(0, 0, 255);
            Console.WriteLine(contours.Size);
            List<Rectangle> rects = new List<Rectangle>();
            //开始遍历
            for (int i = 0; i < contours.Size; i++)
            {
                //得到这个连通区域的外接矩形
                var rect = CvInvoke.BoundingRectangle(contours[i]);
                //如果高度不足，或者长宽比太小，认为是无效数据，否则把矩形画到原图上
                if (rect.Height > 10 && (rect.Width * 1.0 / rect.Height) > 0.2)
                {
                    rects.Add(rect);


                    //CvInvoke.DrawContours(resuImage, contours, i, color);//画轮廓
                    // CvInvoke.Rectangle(resuImage, rect, color);//画矩形框
                   
                    CvInvoke.Rectangle(img, rect, color);//画矩形框

                }
            }

            // return img.ConcateVertical(resuImage).ToBitmap();
            img.Save("bbbb.jpg");
            imageBox3.Image = img;
            imageBox3.Show();
          
        }

        private void 处理ToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            String url = "http://openapi.youdao.com/ocrapi";
            Dictionary<string, string> dic = new Dictionary<string, string>();

            string img = ImgToBase64String("原cai.jpg");
            string appKey = "5bb7ec5e049fd399";
            string detectType = "10011";
            string langType = "zh-en";
            String imageType = "1";
            string salt= DateTime.Now.Millisecond.ToString();
            string appSecret = "t8DfmmwCzdRneiPd0CCbRQo4OvaDPI52";
            MD5 md5 = new MD5CryptoServiceProvider();
            string md5Str = appKey + img + salt + appSecret;
            byte[] output = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(md5Str));
            string sign = BitConverter.ToString(output).Replace("-", "");
            dic.Add("img", System.Web.HttpUtility.UrlEncode(img));
            
            dic.Add("appKey", appKey);
            dic.Add("langType", langType);
            dic.Add("detectType", detectType);
            dic.Add("imageType", imageType);
            dic.Add("salt", salt);
            dic.Add("sign", sign);
            string result = Post(url, dic);
            textBox4.Text = result;

           
            

           
           

           
        }

        protected static string ImgToBase64String(string Imagefilename)
        {
            try
            {
                System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(Imagefilename);

                MemoryStream ms = new MemoryStream();
                bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
                byte[] arr = new byte[ms.Length];
                ms.Position = 0;
                ms.Read(arr, 0, (int)ms.Length);
                ms.Close();
                return Convert.ToBase64String(arr);
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        public static string Post(string url, Dictionary<string,string> dic)
        {
            string result = "";
            HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
            req.Method = "POST";
            req.ContentType = "application/x-www-form-urlencoded";
            #region 添加Post 参数  
            StringBuilder builder = new StringBuilder();
            int i = 0;
            foreach (var item in dic)
            {
                if (i > 0)
                    builder.Append("&");
                builder.AppendFormat("{0}={1}", item.Key, item.Value);
                i++;
            }
            Console.WriteLine(builder.ToString());
            byte[] data = Encoding.UTF8.GetBytes(builder.ToString());
            req.ContentLength = data.Length;
            using (Stream reqStream = req.GetRequestStream())
            {
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();
            }
            #endregion
            HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
            Stream stream = resp.GetResponseStream();
            //获取响应内容  
            using (StreamReader reader = new StreamReader(stream, Encoding.UTF8))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        private void 文本处理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            string result = textBox5.Text;
            int x, y;
            string result2 = "";

            for (int i = 0; i < i+1; i++)
            {
                //字符串提取
                if (result.IndexOf("text", i)==-1)
                {

                    break;
                }
                else
                {
                    x = result.IndexOf("text", i) + 6;  //这是text后面文本的第一个引号位置

                    y = result.IndexOf('"', x + 1);  //从"text"：" 开始找下一个双引号位置
                    result2 = result2 + result.Substring(x + 1, y - x - 1);
                    i = y + 1;
                }
                
            }
            //MessageBox.Show(result2);
            textBox6.AppendText(result2);

        }

        private void 对原图进行文本识别ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String url = "http://openapi.youdao.com/ocrapi";
            Dictionary<string, string> dic = new Dictionary<string, string>();

            string img = ImgToBase64String(pathElec);
            string appKey = "5bb7ec5e049fd399";
            string detectType = "10011";
            string langType = "zh-en";
            String imageType = "1";
            string salt = DateTime.Now.Millisecond.ToString();
            string appSecret = "t8DfmmwCzdRneiPd0CCbRQo4OvaDPI52";
            MD5 md5 = new MD5CryptoServiceProvider();
            string md5Str = appKey + img + salt + appSecret;
            byte[] output = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(md5Str));
            string sign = BitConverter.ToString(output).Replace("-", "");
            dic.Add("img", System.Web.HttpUtility.UrlEncode(img));

            dic.Add("appKey", appKey);
            dic.Add("langType", langType);
            dic.Add("detectType", detectType);
            dic.Add("imageType", imageType);
            dic.Add("salt", salt);
            dic.Add("sign", sign);
            string result = Post(url, dic);
            //对结果进行处理

            int x, y;
            string result2 = "";

            for (int i = 0; i < i + 1; i++)
            {
                //字符串提取
                if (result.IndexOf("text", i) == -1)
                {

                    break;
                }
                else
                {
                    x = result.IndexOf("text", i) + 6;  //这是text后面文本的第一个引号位置

                    y = result.IndexOf('"', x + 1);  //从"text"：" 开始找下一个双引号位置
                    result2 = result2 + result.Substring(x + 1, y - x - 1);
                    i = y + 1;
                }

            }
            //MessageBox.Show(result2);
            textBox7.AppendText(result2);


        }

        private void 对比图文本识别ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            String url = "http://openapi.youdao.com/ocrapi";
            Dictionary<string, string> dic = new Dictionary<string, string>();

            string img = ImgToBase64String(pathScan);
            string appKey = "5bb7ec5e049fd399";
            string detectType = "10011";
            string langType = "zh-en";
            String imageType = "1";
            string salt = DateTime.Now.Millisecond.ToString();
            string appSecret = "t8DfmmwCzdRneiPd0CCbRQo4OvaDPI52";
            MD5 md5 = new MD5CryptoServiceProvider();
            string md5Str = appKey + img + salt + appSecret;
            byte[] output = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(md5Str));
            string sign = BitConverter.ToString(output).Replace("-", "");
            dic.Add("img", System.Web.HttpUtility.UrlEncode(img));

            dic.Add("appKey", appKey);
            dic.Add("langType", langType);
            dic.Add("detectType", detectType);
            dic.Add("imageType", imageType);
            dic.Add("salt", salt);
            dic.Add("sign", sign);
            string result = Post(url, dic);
            //对结果进行处理

            int x, y;
            string result2 = "";

            for (int i = 0; i < i + 1; i++)
            {
                //字符串提取
                if (result.IndexOf("text", i) == -1)
                {

                    break;
                }
                else
                {
                    x = result.IndexOf("text", i) + 6;  //这是text后面文本的第一个引号位置

                    y = result.IndexOf('"', x + 1);  //从"text"：" 开始找下一个双引号位置
                    result2 = result2 + result.Substring(x + 1, y - x - 1);
                    
                    i = y + 1;
                }

            }
            //MessageBox.Show(result2);
            textBox8.AppendText(result2);
        }
    }//class结束
}
